package com.xxg.renrenshoppingcart.config;

import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xxg.renrencommon.util.JwtUtils;
import com.xxg.renrenshoppingcart.exception.ErrorMessage;
import org.apache.tomcat.util.http.MimeHeaders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.HashMap;

/**
 * rest接口拦截器，预处理header参数进行token校验
 *
 * @author xxg
 * @date 2020/10/28
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        // token验证
        if (token != null) {
            DecodedJWT decodedToken;
            try {
                decodedToken = JwtUtils.verifyJwtToken(token, JwtUtils.SECRET);
            } catch (JWTVerificationException e) {
                logger.error(ErrorMessage.VERIFY_TOKEN_ERROR, e);
                response.sendError(401, "Unauthorized");
                return false;
            }
            String userId = decodedToken.getClaim("userId").asString();
            String type = decodedToken.getClaim("type").asString();
            HashMap<String, String> map = new HashMap<>(4);
            map.put("userId", userId);
            map.put("type", type);
            reflectSetHeader(request, map);
            return true;
        }
        response.sendError(401, "Unauthorized");
        return false;
    }

    /**
     * 修改header信息，key-value键值对儿加入到header中
     *  @param request 请求体
     * @param map 需要加入header的参数
     */
    private void reflectSetHeader(HttpServletRequest request, HashMap<String, String> map) {
        Class<? extends HttpServletRequest> requestClass = request.getClass();
        try {
            Field request1 = requestClass.getDeclaredField("request");
            request1.setAccessible(true);
            Object o = request1.get(request);
            Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
            coyoteRequest.setAccessible(true);
            Object o1 = coyoteRequest.get(o);
            Field headers = o1.getClass().getDeclaredField("headers");
            headers.setAccessible(true);
            MimeHeaders o2 = (MimeHeaders) headers.get(o1);
            map.forEach((key, value) -> o2.addValue(key).setString(value));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
